﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RayDen.Library.Components.Color.Types;
using RayDen.Library.Core.Primitives;
using RayDen.Library.Data;
using RayDen.Library.Entity.Scene;
using RayDen.RayEngine;
using RayEngine.Spectral.Entities.Textures;

namespace RayEngine.Spectral.Entities.Materials
{
    [Flags]
    public enum MaterialOptions
    {
        WavelengthDependent = 0x02,
        Fluorescent = 0x04,
        SubsurfaceScattering = 0x08,


    }


    public abstract class BaseMaterial
    {
        public int Id;
        public string Name;
        public IValueTexture Diffuse;
        public IValueTexture Specular;
        public IValueTexture Transmission;
        public IValueTexture Glossy;
        public IValueTexture Bump;
        public IValueTexture Alpha;
        public IValueTexture Emittance;
        public IValueTexture Reflectance;
        public IValueTexture Custom;
        public float Exponent;

        public IWavelengthDependentValue IndexOfRefraction;
        public IWavelengthDependentValue Absorbtion;
        public IWavelengthDependentValue Scattering;

        public MaterialOptions Options;

        protected MaterialInfo mi;

        protected BaseMaterial()
        {
        }

        protected BaseMaterial(MaterialInfo mi, RayEngineScene scene)
        {
            this.mi = mi;

            this.Exponent = mi.Exponent;
            this.IndexOfRefraction = (ConstWavelengthDependentValue)mi.MediumInfo.IoR;

            if (mi.DiffuseTexture != null)
            {
                Diffuse =
                    TextureFactory.Instance.CreateImageTexture(
                        (RgbSpectrumTexture)scene.Query(mi.MaterialName, TextureType.Diffuse));
            }
            else
            {
                Diffuse = TextureFactory.Instance.CreateConstTexture(ref mi.Kd);
            }

            if (mi.Specular != null)
            {
                Specular =
                    TextureFactory.Instance.CreateImageTexture(
                        (RgbSpectrumTexture)scene.Query(mi.MaterialName, TextureType.Specular));
            }
            else
            {
                Specular = TextureFactory.Instance.CreateConstTexture(ref mi.Kr);
            }

            if (mi.AlphaTexture != null)
            {
                Alpha =
                    TextureFactory.Instance.CreateImageTexture(
                        (RgbSpectrumTexture)scene.Query(mi.MaterialName, TextureType.Alpha));            
            }

            var zeroSpectrum = RgbSpectrum.ZeroSpectrum();
            var zeroTex = TextureFactory.Instance.CreateConstTexture(ref zeroSpectrum);

            if (mi.BumpTexture != null && scene.OptTextures.Contains(mi.BumpTexture))
            {
                Bump =
                    TextureFactory.Instance.CreateImageTexture(
                        (RgbSpectrumTexture)scene.Query(mi.MaterialName, TextureType.Bump));
            }
            //else
            //{
            //    Bump = zeroTex;
            //}

            if (!mi.GlossReflectance.IsBlack())
            {
                Glossy = TextureFactory.Instance.CreateConstTexture(ref mi.Ks);
            }
            //else
            //{
            //    Glossy = zeroTex;
            //}

            if (!mi.Kt.IsBlack())
            {
                Transmission = TextureFactory.Instance.CreateConstTexture(ref mi.Kt);
            }
            //else
            //{
            //    Transmission = zeroTex;
            //}

            if (!mi.Reflectance.IsBlack())
            {
                Reflectance = TextureFactory.Instance.CreateConstTexture(ref mi.Reflectance);
            }
            //else
            //{
            //    Reflectance = zeroTex;
            //}
        }
    }
}
